package com.sp.homework;

/**
 * 面试题
 *
 * A线程打印A
 * B线程打印B
 * C线程打印C
 * 交替打印ABCABC...打印100个字符
 *
 * 解读: 关键点是怎么依次唤醒这三个线程, 并且还有一个全局的变量去计数
 *      判断三个线程打印时处于什么状态, 然后去打印, 打印完之后进入阻塞状态
 *      三个线程涉及到线程之间的通信, 所以肯定是阻塞在同一个对象上的
 */
public class ThreadPrintTest {

    /**
     * 状态的变量
     * 0-A 1-B 2-C
     */
    private static Integer state = 0;

    //定义一个Object对象, 作为全局的锁
    private static Object lock = new Object();

    //计数1-100
    private static Integer count = 0;

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            while (true) {
                synchronized (lock){
                    if (count + 1 <= 100 && state == 0) {
                        System.out.println(count + ": A " + Thread.currentThread().getName());
                        lock.notifyAll();
                        count ++;
                        state = 1;
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        Thread t2 = new Thread(() -> {
            while (true) {
                synchronized (lock){
                    if (count + 1 <= 100 && state == 1) {
                        System.out.println(count + ": B " + Thread.currentThread().getName());
                        lock.notifyAll();
                        count ++;
                        state = 2;
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        Thread t3 = new Thread(() -> {
            while (true) {
                synchronized (lock){
                    if (count + 1 <= 100 && state == 2) {
                        System.out.println(count + ": C " + Thread.currentThread().getName());
                        lock.notifyAll();
                        count ++;
                        state = 1;
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });

        t1.start();
        t1.setName("t1");
        t2.start();
        t2.setName("t2");
        t3.start();
        t3.setName("t3");
    }
}
